#include "gc.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "Path.h"

typedef std::vector<int> LabelSet;
typedef std::map<int, LabelSet> LabelMap;

void evaluate (std::string truthPathName, int truthPathNo, 
	       std::string truthImageFileTemplate, 
	       std::string resPathName, int resPathNo)
{
  ListOfPaths truthPathList, resPathList;
  truthPathList.readXMLPaths(truthPathName.c_str());
  resPathList.readXMLPaths(resPathName.c_str());
  Path truthPath = truthPathList.get(truthPathNo);
  Path resPath = resPathList.get(resPathNo);
  int truthStartSliceNo = truthPath.lastSlice();
  int truthEndSliceNo = truthPath.firstSlice();
  int truthSliceNum = truthEndSliceNo - truthStartSliceNo + 1;
  int resStartSliceNo = resPath.lastSlice();
  int resEndSliceNo = resPath.firstSlice();
  int resSliceNum = resEndSliceNo - resStartSliceNo + 1;
  LabelMap truthLabelMap;
  for (int truthSliceNo = truthStartSliceNo; truthSliceNo <= truthEndSliceNo; 
       truthSliceNo++) {
    for (int truthIndex = 0; truthIndex < truthPath.size(); truthIndex++) {
      if (truthPath.getSliceAtIndex(truthIndex) == truthSliceNo) {
	truthLabelMap[truthSliceNo].push_back(truthPath.getLabelAtIndex(truthIndex));
      }
    }
  }
  int correctRegionNum = 0;
  int totalCorrectRegionNum = truthPath.size();
  for (int resIndex = resPath.size() - 1; resIndex >= 0; resIndex--) {
    int resSliceNo = resPath.getSliceAtIndex(resIndex);
    char fn[200];
    sprintf(fn, truthImageFileTemplate.c_str(), resSliceNo);
    LabelImage::Pointer image = readLabelImage(fn);
    LabelImage::IndexType index;
    index[0] = resPath.getXAtIndex(resIndex);
    index[1] = resPath.getYAtIndex(resIndex);
    int resLabel = image->GetPixel(index);
    if (truthLabelMap.count(resSliceNo) > 0) {
      for (LabelSet::const_iterator itr = truthLabelMap[resSliceNo].begin(); 
	   itr != truthLabelMap[resSliceNo].end(); itr++) {
	if (*itr == resLabel) {
	  correctRegionNum++;
	  break;
	}
      }
    }
  }
  std::cout << "Correctness: " 
	    << double(correctRegionNum) / double(totalCorrectRegionNum)
	    << " (" << correctRegionNum << "/" 
	    << totalCorrectRegionNum << ")" << std::endl;
}



int main (int argc, char* argv[])
{
  int argNo = 1;
  std::string truthPathName = argv[argNo++];
  int truthPathNo = atoi(argv[argNo++]);
  std::string truthImageFileTemplate = argv[argNo++];
  std::string resPathName = argv[argNo++];
  int resPathNo = atoi(argv[argNo++]);
  evaluate(truthPathName, truthPathNo, truthImageFileTemplate, 
	   resPathName, resPathNo);
  return 0;
}
